/**
 * 定时抓取asa/asc数据及上报服务
 * @author Stay
 * @type {e | (() => Express) | (function(): function(*, *, *): void)}
 */
const express = require('express');
const cron = require('node-cron');
const AppleSearchAds = require('./src/fetchCampaignData');
const AppleStoreService = require('./src/fetchSalesData');
const fs = require('fs');
const path = require('path');
const HttpUtil = require('./src/util/http_util');
const cfg = require('./src/appConfig');
const { getNextDateWithDays, getNextDate } = require("./src/util/app_util");
require("./src/util/logger");

// 读取配置文件
const config = JSON.parse(fs.readFileSync('public/config.json', 'utf8'));

const app = express();
const port = 3003;
const { orgId, teamId, clientId, keyId, adamIds, privateKeyFile, issuerId, keyId2, p8File, vendorNumber } = config;
const privateKeyPath = path.join(__dirname, 'public', privateKeyFile);
const p8Path = path.join(__dirname, 'public', p8File);
const appleSearchAds = new AppleSearchAds(teamId, clientId, keyId, privateKeyPath, orgId);
const appleStoreService = new AppleStoreService(issuerId, keyId2, p8Path);

// 入口
main()

app.get('/', (req, res) => {
    res.send('Apple Search Ads Data Fetcher is running.');
});

app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`);
    // 立即执行一次，以验证功能
    const strDate = '2024-08-08';
    const endDate = '2024-08-08';
    for (const adamId of adamIds) {
        console.log(`Fetching campaign data for adamId: ${adamId}`);
        fetchAndReportCampaignData(strDate, endDate, adamId);
    }

    const strDate1 = '2024-08-08';
    const endDate2 = '2024-08-08';
    console.log(`fetchAndReportSales start, date: ${strDate1}~${endDate2}`);
    //循环从开始日期到结束日期，循环获取销售数据
    for (let date = strDate1; date <= endDate2; date = getNextDate(date)) {
        fetchAndReportSales(date, vendorNumber);

        //如果日期是最后一天，打印提示任务完成
        if (date === endDate2) {
            console.log('fetchSalesData 任务执行完成✅');
        }
    }
});

// 定时任务入口
function main() {
    // 定时任务，每天凌晨 0:05 执行 '5 0 * * *'
    // 测试定时任务，每3分钟执行 '*/3 * * * *'
    cron.schedule('5 0 * * *', async () => {
        const startTime = getNextDateWithDays(); // 根据需求动态设置开始时间
        const endTime = getNextDateWithDays(); // 根据需求动态设置结束时间
        console.log(`fetchAndReportCampaignData date: ${startTime} ~ ${endTime}`);

        for (const adamId of adamIds) {
            console.log(`Fetching campaign data for adamId: ${adamId}`);
            await fetchAndReportCampaignData(startTime, endTime, adamId);
        }
    });

    // 每天凌晨0:05执行 5 0 * * *
    cron.schedule('5 0 * * *', () => {
        const strDate = getNextDateWithDays(-2);
        const endDate = getNextDateWithDays(-2);

        console.log(`fetchAndReportSales start, date: ${strDate}~${endDate}`);
        //循环从开始日期到结束日期，循环获取销售数据
        for (let date = strDate; date <= endDate; date = getNextDate(date)) {
            fetchAndReportSales(date, vendorNumber);

            //如果日期是最后一天，打印提示任务完成
            if (date === endDate) {
                console.log('fetchSalesData 任务执行完成✅');
            }
        }
    });
}

function fetchAndReportSales(date, vendorNumber) {
    console.log(`fetchAndReportSales date: ${date}, vendorNumber: ${vendorNumber}`);
    appleStoreService.fetchSalesReportWithCurl(date, vendorNumber).then(data => {
        console.log('fetchAndReportSales parsed data:', data.length);
        if (data && data.length > 0) {
            console.log('fetchAndReportSales 数据上报中');
            // 成功后通过 HTTP POST 提交数据
            let retryCount = 0;
            const maxRetries = 3;
            const retryInterval = 60000; // 1分钟

            function postWithRetry() {
                HttpUtil.post(cfg.REPORT_SALES_DATA_URL, data)
                    .then(res => {
                        // 打印状态码和返回值
                        console.log(`fetchAndReportSales 上报成功！状态码: ${res.status} 返回值: ${JSON.stringify(res.data)}`);
                    })
                    .catch(error => {
                        console.error('fetchAndReportSales 上报失败');
                        if (retryCount < maxRetries) {
                            retryCount++;
                            console.log(`尝试第 ${retryCount} 次重试，1分钟后重试...`);
                            setTimeout(postWithRetry, retryInterval);
                        } else {
                            console.error(`fetchAndReportSales 上报失败，已重试 ${maxRetries} 次`);
                        }
                    });
            }

            postWithRetry();
        } else {
            console.log('fetchAndReportSales 没有数据需要上报');
        }
    }).catch(error => {
        console.error('fetchAndReportSales 抓取数据失败');
    });
}

function fetchAndReportCampaignData(startTime, endTime, adamId) {
    appleSearchAds.fetchCampaignData(startTime, endTime, adamId).then(data => {
        if (data.error && data.error.errors && data.error.errors.length > 0) {
            const errorMessage = data.error.errors[0].message;
            console.error(`fetchAndReportCampaignData 抓取数据失败: ${errorMessage}`);
            return;
        }

        if (!data.data || !data.data.reportingDataResponse || !data.data.reportingDataResponse.row
            || data.data.reportingDataResponse.row.length === 0) {
            console.log(`fetchAndReportCampaignData ${adamId} ${startTime}~${endTime} 没有数据需要上报`);
            return;
        }

        console.log(`fetchAndReportCampaignData ${adamId} ${startTime}~${endTime} 抓取成功，上报中...`);

        // 成功后通过 HTTP POST 提交数据
        let retryCount = 0;
        const maxRetries = 5;
        const retryInterval = 60000; // 1分钟

        function postWithRetry() {
            HttpUtil.post(cfg.REPORT_CAMPAIGN_DATA_URL, data)
                .then(res => {
                    //打印状态码和返回值
                    console.log(`fetchAndReportCampaignData 上报成功！状态码: ${res.status} 返回值: ${JSON.stringify(res.data)}`);
                })
                .catch(error => {
                    console.error(`fetchAndReportCampaignData 上报失败`);
                    if (retryCount < maxRetries) {
                        retryCount++;
                        console.log(`尝试第 ${retryCount} 次重试，1分钟后重试...`);
                        setTimeout(postWithRetry, retryInterval);
                    } else {
                        console.error(`fetchAndReportCampaignData 上报失败，已重试 ${maxRetries} 次`);
                    }
                });
        }

        postWithRetry();
    }).catch(error => {
        console.error(`fetchAndReportCampaignData 抓取数据失败`);
    });
}